using System;

/// Why wrap Action into Signal? Because an Action (delegate) is immutable, you cannot WaitAction(xxxAction) directly.
public class Signal
{
    public object data { get; protected set;}
    public Action listener { get { return _listener; } }
    protected Action _listener;

    public void Connect(Action listener)
    {
        if (_listener != null) throw new System.Exception(@"Signal.Connect failed, signal already connected! 
Please call Disconnect first before reconnect to another listener");

        _listener = listener;
    }

    public void Disconnect()
    {
        if (_listener == null) throw new System.Exception(@"Signal.Disconnect failed, no listener connected!");

        _listener = null;
    }

    public void Emit(int code)
    {
        this.data = code;
        if (_listener != null) _listener();
    }

    public void Emit()
    {
        data = 1;
        if (_listener != null) _listener();
    }

    public bool IsConnected()
    {
        return _listener != null;
    }

    public void Reset()
    {
        data = 0;
    }
}

public class Signal<T>
{
    public T data { get; protected set; }
    public Action<T> listener { get { return _listener; } }
    protected Action<T> _listener;

    public void Connect(Action<T> listener)
    {
        if (_listener != null) throw new System.Exception(@"Signal.Connect failed, signal already connected! 
Please call Disconnect first before reconnect to another listener");

        _listener = listener;
    }

    public void Disconnect()
    {
        if (_listener == null) throw new System.Exception(@"Signal.Disconnect failed, no listener connected!");

        _listener = null;
    }

    public void Emit(T code)
    {
        this.data = code;
        if (_listener != null) _listener(code);
    }

    public bool IsConnected()
    {
        return _listener != null;
    }

    public void Reset()
    {
        data = default(T);
    }
}